import React, { Component } from 'react'
import style from './style'
import cx from 'classnames'
import Button from '../button'
import IconFont from '../iconFont'
import util from '../util'
import tc from 'textarea-caret'
import PicUploader from './PicUploader'

class PostFrame extends Component {

  static propsType = {
    multi: React.PropTypes.bool,
    label: React.PropTypes.string,
    btn: React.PropTypes.string,
    atData: React.PropTypes.array,
    load: React.PropTypes.func,
    post: React.PropTypes.func,
    uploadPic: React.PropTypes.func,
    uploadedPics: React.PropTypes.array,
    clearUploadedPics: React.PropTypes.func
  }

  static defaultProps = {
    post: () => {},
    clearUploadedPics: () => {},
    uploadedPics: []
  }

  selectMap = {}

  state = {
    active: false,
    colored: false,
    post: '',
    showList: false,
    showPicUploader: false,
    listPosition: {},
    query: '',
    top: false
  }

  handleFocus = (e) => {
    this.setState({
      active: true,
      colored: true
    })
  }

  handleClick = (e) => {
    setTimeout(() => {
      this.handleKeyUp(e)
    }, 0)
  }

  handleBlur = () => {
    this.setState({
      colored: false
    })

    setTimeout(() => {
      this.hideList()
    }, 150)
  }

  handleChange = () => {
    this.setState({
      post: this.refs.input.value
    })
  }

  hideList() {
    this.setState({
      showList: false
    })
  }

  handleSelect = selected => {
    this.hideList()
    const obj = this.props.atData[selected]
    const el = this.refs.input
    let { start, end } = util.getCursorPos(el)
    
    if (start == null) {
      start = this.caret.start
      end = this.caret.end
      el.focus()
    }

    const { value } = el

    this.setState({
      post: value.slice(0, start).replace(/(@[^@\s\n]*)$/, (whole, _match) => whole.replace(_match, '@' + obj.fullName)) +' '+ value.slice(start)
    })

    setTimeout(() => {
      el.selectionStart = start + obj.fullName.length +1
      el.selectionEnd = end + obj.fullName.length +1
    }, 0)

    this.selectMap[obj.fullName] = obj
  }

  handleKeyUp = (e) => {
    const { which } = e
    if (which === 16 || which === 13) return

    const el = this.refs.input
    const { value } = el
    const { start, end } = util.getCursorPos(el)

    const leftPart = value.slice(0, start)
    const rightPart = value.slice(start)
    const match = leftPart.match(/@([^@\s\n]*)$/)

    if (match === null) {
      this.hideList()
      return
    }

    const query = match[1] || ''

    this.setState({query})

    util.throttle(   
      () => {
        this.props.load(query)
      },
      300
    )

    let { top, left } = tc(el, end - query.length)

    const showList = match !== null
    let listPosition = { left: left+'px' }

    if (showList) {
      // 计算位置
      const { clientHeight } = document.documentElement
      const { top:_top } = el.getBoundingClientRect()

      // 列表向上
      if (_top + 71 > clientHeight/2) {
        listPosition.bottom = '100%'
        listPosition.marginBottom = '-4px'
      } else {
        listPosition.top = top + (this.props.multi? 28: 24) - el.scrollTop + 'px'
      }
    }

    this.setState({
      showList,
      listPosition
    })

    if (match) {
      this.caret = {
        start,
        end
      }
    }
  }

  handleSmile() {}

  handleAit() {
    console.log('dd')
  }


  hidePicUploader() {
    this.setState({
      showPicUploader: false
    })
    this.refs.file.value = ''
  }
  
  handlePic() {
    this.refs.file.click()
  }

  handlePicChange() {

    this.setState({
      showPicUploader: true
    })

    const { files } = this.refs.file
    const file = files[0]

    // 上传
    this.props.uploadPic(file)

		// reset
		this.refs.file.value = ''
  }

  post() {
    const format = 
      str => str
        .replace(/[^\s\n](@[^@\s\n]+)/g, (whole, match) => whole.replace(match, ' ' + match))
        .trim()

    this.props.post({ 
      images: this.props.uploadedPics.filter(pic => !pic._uuid), 
      content: format(this.state.post) , 
      selectMap: this.selectMap})

    this.clear()
  }

  clear() {
    this.props.clearUploadedPics()
    this.setState({
      post: '',
      showPicUploader: false
    })
  }

  renderAddon = (addon, i) => {
    return (
      <li 
        onClick={::this[`handle${util.upperInitial(addon)}`]}
        key={i}
      >
        <IconFont value={addon}/>
        {
          addon === 'pic'? <input type="file" ref="file" onChange={::this.handlePicChange}/>: null
        }
      </li>
    )
  }

  componentWillReceiveProps(props) {
    if (props.uploadedPics && props.uploadedPics.length) {
      // 有上传完的图片时，
      // 可以发布
      if (props.uploadedPics.some(pic => !pic._uuid)) {
        const notNull = this.state.post.trim().length
        // 没有post时
        if (!notNull) {
          this.setState({
            post: '发布图片'
          })
        }
      }
    }
  }

  render() {
    const { className, addons, multi, label, btn, ...others } = this.props
    const classNames = cx({
      [style.root]: true,
      [className]: !!className,
      [style.active]: this.state.active,
      [style.showPicUploader]: this.state.showPicUploader,
      [style.colored]: this.state.colored,
      [style.textarea]: multi,
      [style.input]: !multi
    })
    const disabled = !this.state.post.trim().length
    return (
      <div 
        className={classNames}
      >
        { 
          React.createElement(multi? 'textarea': 'input', {
            className: cx({
              [style.frame]: true
            }),
            onFocus: this.handleFocus,
            onClick: this.handleClick,
            onBlur: this.handleBlur,
            onChange: this.handleChange,
            onKeyUp: this.handleKeyUp,
            ref: 'input',
            value: this.state.post,
            placeholder: label
          }) 
        }
        <div ref="handle" className={style.handle}>
          {
            addons?
          <div className={style.addons}>
            <ul>{ addons.map(this.renderAddon) }</ul>
          </div>: null
          }
          <Button 
            onClick={::this.post}
            className={style.btn}
            disabled={disabled}
            label={btn}
          />
        </div>
        {
          React.Children.map(this.props.children, child => React.cloneElement(child, {
            ref: 'atList',
            show: this.state.showList,
            pos: this.state.listPosition,
            data: this.props.atData,
            handleSelect: this.handleSelect,
            query: this.state.query
          }))
        }
        <PicUploader 
          pics={this.props.uploadedPics}
          add={this.props.uploadPic}
          clear={this.props.clearUploadedPics}
          close={this.hidePicUploader.bind(this)}
          show={this.state.showPicUploader}
        />
      </div>
    )
  }
}

export default PostFrame
